home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
pcrng.zip
/
RMUNI.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-06-29
|
15KB
|
367 lines
.8087
page ,132
;
;***********************************************************************
;* Here are data declarations for use by RINIT, IVNI, IUNI, VNI, UNI. *
;* All routines are written for use with IBM Fortran/2 Compiler. *
;* *
;* Authors: G. Marsaglia, B. Narasimhan and Arif Zaman *
;* Supercomputer Computations Research Institute *
;* and *
;* Department of Statistics *
;* Florida State University *
;* Tallahassee, Fl 32306-3033. *
;***********************************************************************
;
.MODEL small ;Use small memory model
TITLE 'A Random Number Generator for PC's.'
;
;---------------Equates-----------------
;
arg_offset equ 6 ;Offset of argument.
c_low equ 0cbb1h
c_high equ 74h ;C = 7654321 initially.
cons_low equ 55e5h
cons_high equ 159ah ;Constant = 362436069.
no_of_bits equ 32
top_of_list equ 168
init_i_val equ top_of_list
init_j_val equ 84
;
datseg segment para 'F@DATA'
;
; Table for Generator (Default values).
;
unitabl dd 0F83CEE7Bh
dd 0A83E5AD3h
dd 036200BBh
dd 0FA5764F6h
dd 0A13CBFC4h
dd 565A191Eh
dd 14D4CCFBh
dd 7F5AD22Ch
dd 03528F2Eh
dd 0E81E32DDh
dd 71C47276h
dd 0AA0F8045h
dd 3C3F1C78h
dd 0E8CE101Dh
dd 0CCC12691h
dd 47196DBFh
dd 074A6DFFh
dd 03FB675Eh
dd 60436236h
dd 072F0247h
dd 0C7E9185h
dd 0CE579EAEh
dd 01864E96h
dd 0A526C5C6h
dd 0F582EB0Dh
dd 0AFE827F4h
dd 55CED836h
dd 26124C49h
dd 7049AEE1h
dd 49552795h
dd 0D1602ED6h
dd 051C65CEh
dd 0AEF3CC37h
dd 0A83880ABh
dd 0AE7EE06Ah
dd 0D64D988Bh
dd 0A96BC73h
dd 0ECEF4297h
dd 6C18300Dh
dd 22F3A897h
dd 0B4D760ADh
dd 0AC838383h
dd 0FD04E68Fh
;
i dw 164
j dw 80 ;Indices I and J.
c dd 0EADA75CCh ;Constant C.
mod169 db 169
mod179 db 179
multiplier db 53
carry db 1 ;Carry bit (Default).
stored_val dd 122a70c3h
datseg ends
;
;***********************************************************************
;* Subroutine RINIT takes an 8-digit number as argument. Use as *
;* CALL RINIT(I) *
;* *
;* Purpose: Seeds the table and prepares pointers for use by other *
;* routines. *
;* *
;* This is set up for use with IBM Fortran/2 Compiler. *
;* -----Note that a 8087 co-processor is assumed to be present.------- *
;* *
;* Authors: G. Marsaglia, B. Narasimhan and A. Zaman *
;* Supercomputer Computations Research Institute *
;* and *
;* Department of Statistics *
;* Florida State University *
;* Tallahassee, Fl 32306-3033. *
;***********************************************************************
;
rseg segment 'CODE'
;
assume cs:rseg, ds:datseg
rinit proc Far
public rinit
;
; Usual IBM Fortran/2 stuff....
;
push bp ;Save caller's BP.
mov bp,sp ;Ready to address.
;
; No traceback needed.
;
mov ax,datseg ;DATA segment.
mov ds,ax
;
; Load parameter and strip two digits at a time to get four seed values.
;
les si,DWORD PTR[bp].arg_offset
mov ax,Word Ptr es:[si]
mov dx,Word Ptr es:[si]+2
mov cx,10000
div cx
mov cl,100
div cl
mov bx,ax ;BH = K, BL = L.
mov ax,dx
div cl
mov dl,ah
mov dh,al ;DH = J, DL = I.
;
; Add one to all to make sure they are non-zero.
;
inc dl
inc dh
inc bh
inc bl
;
; DL = I, DH = J, BL = L, BH = K.
;
xor si,si ;Table Index.
labl01:
;
; Result will be in [BP,DI].
;
xor di,di
xor bp,bp
mov cx,no_of_bits ;Bit counter.
labl02:
shl di,1
rcl bp,1 ;Result *= 2.
mov al,dh ;AL = J.
mul bh ;AX = J * K.
div mod179
mov al,ah ;AL = AX mod 179.
mul dl ;AX = AX * I.
div mod179
mov dl,dh ;I = J.
mov dh,bh ;J = K.
mov bh,ah ;K = new K.
;
mov al,bl ;AL = L.
mul multiplier
inc ax
div mod169
mov bl,ah ;L = 53*L+1 mod 169.
;
mov al,bl ;AL = new L.
mul bh ;AX = L * K.
and ax,63 ;Mod 64.
cmp ax,32
jl labl03
inc di ;Set low bit.
labl03:
loop labl02
;
mov WORD PTR unitabl[si],di
mov WORD PTR unitabl[si+2],bp ;Save value.
add si,4 ;Bump pointer.
cmp si,172 ;Seeded 86 entries?
jne labl01
;
; Set indices.
;
mov i,init_i_val
mov j,init_j_val
;
; Set carry to zero.
;
mov carry,0
;
; Set constants.
;
mov WORD PTR c,c_low
mov WORD PTR c+2,c_high
;
; Ready the first value.
;
mov ax,offset stored_val
mov bx,seg stored_val
push bx
push ax
call Far Ptr ivni
; FINIT ;Clear 8087.
pop ax
pop ax
;
; Epilogue...
;
pop bp
ret 4
rinit endp
;
;***********************************************************************
;* This proc contains the following functions. *
;* *
;* IVNI : A function that returns a signed random integer between *
;* -2**31 and 2**31-1. *
;* IUNI : A function that returns a positive random integer *
;* between 0 and 2**31-1. *
;* VNI : A function that returns a signed random uniform between *
;* -1 and 1. *
;* UNI : A function that returns a positive random uniform *
;* between 0 and 1. *
;* *
;* All routines mix a subtract-with-borrow generator and an *
;* arithmetic sequence: *
;* x(n) = x(n-22) - x(n-43) - carry mod 2**32-5. *
;* c = c + 362436069 mod 2**32. *
;* result = x(n) - c mod 2**32. *
;* *
;* This is set up for use with IBM Fortran/2 Compiler. *
;* -----Note that a 8087 co-processor is assumed to be present.------- *
;* *
;* Authors: G. Marsaglia, B. Narasimhan and A. Zaman *
;* Supercomputer Computations Research Institute *
;* and *
;* Department of Statistics *
;* Florida State University *
;* Tallahassee, Fl 32306-3033. *
;***********************************************************************
;
assume cs:rseg, ds:datseg
ivni proc Far ;First entry point.
public ivni
mov ax,datseg
mov ds,ax
jmp ready_next_and_save
;
iuni label Far ;Second entry point.
public iuni
mov ax,datseg
mov ds,ax
and Word Ptr stored_val+2,7fffh ;Mask sign bit.
jmp ready_next_and_save
;
vni label Far ;Third entry point.
public vni
mov ax,datseg
mov ds,ax
mov ax,Word Ptr stored_val
mov bx,Word Ptr stored_val+2
mov di,ax ;Sign is last bit.
jmp normalize
;
uni label Far ;Fourth entry point.
public uni
mov ax,datseg
mov ds,ax
mov ax,Word Ptr stored_val
mov bx,Word Ptr stored_val+2
xor di,di ;Sign should be zero.
;
; Normalize the number.
;
normalize:
mov cx,no_of_bits ;Bit counter.
labl04:
shl ax,1 ; Shift left.
rcl bx,1
jc labl05
loop labl04
jmp ready_next_and_save ;Store zero.
labl05:
add cx,94
mov al,ah
mov ah,bl
mov bl,bh
mov bh,cl
test di,1
jz labl06
stc
labl06:
rcr bx,1
rcr ax,1
mov Word Ptr stored_val, ax
mov Word Ptr stored_val+2,bx
;
FLD DWord Ptr stored_val ;Comply with IBM.
;
ready_next_and_save:
mov di,j ;Load index j.
mov cx,Word Ptr unitabl[di]
mov dx,Word Ptr unitabl[di]+2 ;U(j) in DX, CX.
;
sub di,4 ;j <- j - 4.
jns update_j
mov di,168
update_j:
mov j,di
;
mov si,i ;Load index i.
mov ah,carry ;Load carry.
sahf
sbb cx,Word Ptr unitabl[si]
sbb dx,Word Ptr unitabl[si]+2 ;U(j)-U(i) in DX, CX.
lahf
mov carry,ah ;Save carry.
jnc dont_modify
;
;Negative.
;
sub cx,5 ;Subtract 5.
sbb dx,0
dont_modify:
;
;Save result.
;
mov Word Ptr unitabl[si],cx
mov Word Ptr unitabl[si]+2,dx
;
sub si,4 ;i <- i - 4.
jns update_i
mov si,168
update_i:
mov i,si
;
;Prepare arithmetic sequence.
;
mov ax,Word Ptr c
mov bx,Word Ptr c+2
sub ax,cons_low
sbb bx,cons_high
mov Word Ptr c,ax
mov Word Ptr c+2,bx
;
sub cx,ax
sbb dx,bx
mov ax,Word Ptr stored_val
mov Word Ptr stored_val,cx
mov cx,Word Ptr stored_val+2
mov Word Ptr stored_val+2,dx ;Save for next time.
mov dx,cx ;Comply with IBM
; integer*4.
ret
ivni endp
;
rseg ends
END